#include <parse.h>
#include <config.h>
#include <ctype.h>
#include <types.h>
#include <string.h>
#include <stdio.h>
#include <command.h>

static int parse_line(char *line, char *argv[]) 
{
	int nargs = 0;

	while (nargs < CONFIG_SYS_MAXARGS) {

		/* skip any white space */
		while (isblank(*line))
			++line;

		if (*line == '\0') {    /* end of line, no more args    */
			argv[nargs] = NULL;
			return (nargs);
		}
		argv[nargs++] = line;   /* begin of argument string */

		/* find end of string */
		while (*line && !isblank(*line))
			++line;

		if (*line == '\0') {    /* end of line, no more args    */
			argv[nargs] = NULL;
			return (nargs);
		}

		*line++ = '\0';     /* terminate current arg     */
	}

	return nargs;
}

int run_command(const char *cmd)
{
	char cmdbuf[CONFIG_SYS_CBSIZE];
	char finaltoken[CONFIG_SYS_CBSIZE];
	char *argv[CONFIG_SYS_MAXARGS + 1];	/* NULL terminated  */
	char *str = cmdbuf;
	char *token, *sep;
	int inquotes, argc;
	struct cmd *cmdp;
	int rc = 0;

	if (!cmd || !*cmd) {
		return -1;  /* empty command */
	}

	if (strlen(cmd) >= CONFIG_SYS_CBSIZE) {
		puts ("Command too long!\n");
		return -1;
	}

	strcpy(cmdbuf, cmd);

	while (*str) {
		/*
		 * Find separator, or string end
		 * Allow simple escape of ';' by writing "\;"
		 */
		for (inquotes = 0, sep = str; *sep; sep++) {
			if ((*sep == '\'') && ((sep == str) || (*(sep - 1) != '\\')))
				inquotes = !inquotes;

			if (!inquotes &&
					(*sep == ';') &&    /* separator        */
					( sep != str) &&    /* past string start    */
					(*(sep - 1) != '\\')) /* and NOT escaped  */
				break;
		}

		/*
		 * Limit the token to data between separators
		 */
		token = str;
		if (*sep) {
			str = sep + 1;  /* start of command for next pass */
			*sep = '\0';
		}
		else
			str = sep;  /* no more commands for next pass */

		strcpy(finaltoken, token);

		/* Extract arguments */
		if ((argc = parse_line (finaltoken, argv)) == 0) {
			rc = -1;
			continue;
		}

		/* Look up command in command table */
		if ((cmdp = cmd_search(argv[0])) == NULL) {
			puts("Unknown command '");
			puts(argv[0]);
			puts("' - try 'help'\r\n");
			rc = -1;
			continue;
		}

		/* OK - call function to do the command */
		if ((cmdp->fun) (argc, argv) != 0) {
			rc = -1;
		};
	}

	return rc;
}
